﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sharp3D.Math.Core;
using ReAnimation.Helpers.Common;

namespace GLWrap.SceneObjects.Line
{
    public class DashedLine: BaseLine
    {
        private readonly int DEFAULT_FILL_PERCENT = 100;
        private readonly float DEFAULT_DASH_LENGTH = 0.01f;
        private readonly float DEFAULT_SPACE = 0.025f;
        private float _dashLength;
        private float _spaceLength;
        private int _fillPercent;

        public float SpaceLength
        {
            get
            {
                return _spaceLength;
            }
            set
            {
                _spaceLength = value;
                MarkAsDirty();
            }
        }

        public float DashLength
        {
            get
            {
                return _dashLength;
            }
            set
            {
                _dashLength = value;
                MarkAsDirty();
            }
        }

        public int FillPercent
        {
            get { return _fillPercent; }
            set
            {
                _fillPercent = value;
                MarkAsDirty();
            }
        }

        public DashedLine()
        {
            _fillPercent = DEFAULT_FILL_PERCENT;
            _dashLength = DEFAULT_DASH_LENGTH;
            _spaceLength = DEFAULT_SPACE;
        }

        protected override void InternalRecalculateLineForSceneManager(GlSceneManager sceneManager)
        {
            Vector3F line = PointB - PointA;
            
            Vector3F unitVector = line;
            unitVector.Normalize();

            Vector3F offsetVector = line * (100 - _fillPercent) / 100.0f / 2.0f;
            
            float activePartLength = line.GetLength() * _fillPercent / 100.0f;


            float length = 0;
            int dashesCount = 0;
            int n = 1;
            
            while(length < activePartLength)
            {
                if (n++ % 2 == 0)
                    length += _spaceLength;
                else
                {
                    length += _dashLength;
                    dashesCount++;
                }
            }
                    

            //int dashesCount = (int)(activePartLength / (_dashLength + _spaceLength));

            SynchronizeDashesCount(dashesCount);

            dashesCount.TimesDo((i) =>
                {
                    FullfilledLine dash = (FullfilledLine) AttachedObjects[i];
                    dash.Material = Material;
                    dash.Weight = Weight;
                    dash.PointA = PointA + offsetVector + i * unitVector * _dashLength +i * unitVector * _spaceLength;
                    dash.PointB = dash.PointA + unitVector *_dashLength;
                });
        }

        private void SynchronizeDashesCount(int dashesCount)
        {
            while (dashesCount < AttachedObjects.Count) DetachObject(AttachedObjects[0]);
            while (dashesCount > AttachedObjects.Count) AttachObject(new FullfilledLine());
        }
    }
}
